}
#ifdef HAVE_XDAMAGE
+static void
+finish_frame (GdkGLContext *context)
+{
+ GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+
+ if (context_x11->xdamage == 0)
+ return;
+
+ if (context_x11->frame_fence == 0)
+ return;
+
+ glDeleteSync (context_x11->frame_fence);
+ context_x11->frame_fence = 0;
+ _gdk_x11_surface_set_frame_still_painting (surface, FALSE);
+}
+
static void
bind_context_for_frame_fence (GdkGLContext *context)
{
GdkX11Display *display_x11)
{
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
- GdkSurface *surface = gdk_gl_context_get_surface (context);
XDamageNotifyEvent *damage_xevent;
if (!context_x11->is_attached)
case GL_WAIT_FAILED:
if (wait_result == GL_WAIT_FAILED)
g_warning ("failed to wait on GL fence associated with last swap buffers call");
- glDeleteSync (context_x11->frame_fence);
- context_x11->frame_fence = 0;
- _gdk_x11_surface_set_frame_still_painting (surface, FALSE);
+ finish_frame (context);
break;
/* We assume that if the fence hasn't been signaled, that this
return FALSE;
}
+
+static void
+on_surface_state_changed (GdkGLContext *context)
+{
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+
+ if ((surface->state & GDK_SURFACE_STATE_WITHDRAWN) == 0)
+ return;
+
+ /* If we're about to withdraw the surface, then we don't care if the frame is
+ * still getting rendered by the GPU. The compositor is going to remove the surface
+ * from the scene anyway, so wrap up the frame.
+ */
+ finish_frame (context);
+}
#endif
static gboolean
gdk_x11_surface_get_xid (surface),
XDamageReportRawRectangles);
if (gdk_x11_display_error_trap_pop (display))
- context_x11->xdamage = 0;
+ {
+ context_x11->xdamage = 0;
+ }
else
- g_signal_connect_object (G_OBJECT (display),
- "xevent",
- G_CALLBACK (on_gl_surface_xevent),
- context,
- G_CONNECT_SWAPPED);
+ {
+ g_signal_connect_object (G_OBJECT (display),
+ "xevent",
+ G_CALLBACK (on_gl_surface_xevent),
+ context,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (G_OBJECT (surface),
+ "notify::state",
+ G_CALLBACK (on_surface_state_changed),
+ context,
+ G_CONNECT_SWAPPED);
+
+ }
}
#endif